package core;

import java.awt.Component;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.LinkedList;
import java.util.Queue;

/**
 * Updates GameActions and queues mouse events.
 * 
 * @author Jason
 * 
 */
public class InputManager implements KeyListener, MouseListener,
		MouseMotionListener, MouseWheelListener {

	private Queue<MouseEvent> mouseInputQueue = new LinkedList<MouseEvent>();
	private final GameKeyAction[] keyMap = new GameKeyAction[600];

	/**
	 * Constructs an input manager to listen for events on the given component.
	 * 
	 * @param comp
	 *            The component that mouse and keyboard listeners will be added
	 *            to.
	 */
	public InputManager(Component comp) {
		comp.addKeyListener(this);
		comp.addMouseListener(this);
		comp.addMouseMotionListener(this);
		comp.addMouseWheelListener(this);
		comp.setFocusTraversalKeysEnabled(false);
	}

	/**
	 * Binds a keystroke to a GamekeyAction.
	 * 
	 * @return The old GameKeyAction associated with this keystroke.
	 */
	public synchronized GameKeyAction bind(int keystroke, GameKeyAction action) {
		GameKeyAction ret = keyMap[keystroke];
		keyMap[keystroke] = action;
		return ret;
	}

	private Queue<MouseEvent> altQueue = new LinkedList<MouseEvent>();

	/**
	 * Gets all the mouse events that occurred since the last time this method
	 * was called.
	 */
	public synchronized Queue<MouseEvent> getMouseEvents() {
		altQueue.clear();
		Queue<MouseEvent> temp = mouseInputQueue;
		mouseInputQueue = altQueue;
		altQueue = temp;
		return altQueue;
	}

	@Override
	public synchronized void mouseWheelMoved(MouseWheelEvent e) {
		mouseInputQueue.add(e);
	}

	@Override
	public synchronized void keyPressed(KeyEvent e) {
		GameKeyAction action = keyMap[e.getKeyCode()];
		if (action != null)
			action.press();
	}

	@Override
	public synchronized void keyReleased(KeyEvent e) {
		GameKeyAction action = keyMap[e.getKeyCode()];
		if (action != null)
			action.release();
	}

	@Override
	public synchronized void keyTyped(KeyEvent e) {
		// Do Nothing
	}

	@Override
	public synchronized void mouseDragged(MouseEvent e) {
		mouseInputQueue.add(e);
	}

	@Override
	public synchronized void mouseMoved(MouseEvent e) {
		mouseInputQueue.add(e);
	}

	@Override
	public synchronized void mouseClicked(MouseEvent e) {
		mouseInputQueue.add(e);
	}

	@Override
	public synchronized void mouseEntered(MouseEvent e) {
		mouseInputQueue.add(e);
	}

	@Override
	public synchronized void mouseExited(MouseEvent e) {
		mouseInputQueue.add(e);
	}

	@Override
	public synchronized void mousePressed(MouseEvent e) {
		mouseInputQueue.add(e);
	}

	@Override
	public synchronized void mouseReleased(MouseEvent e) {
		mouseInputQueue.add(e);
	}

}
